package io.renren.common.utils;

import io.renren.common.constant.OjConstant;
import io.renren.config.OjRapidApiConfig;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;

import java.io.IOException;

@Slf4j
@Configuration
public class OjRapidApiUtil {

    @Autowired
    private OjRapidApiConfig ojRapidApiConfig;


    public Response getStatus() throws IOException {
        OkHttpClient client = new OkHttpClient();

        Request request = new Request.Builder()
                .url("https://" + ojRapidApiConfig.getHost() + "/statuses")
                .get()
                .addHeader("x-rapidapi-key", ojRapidApiConfig.getKey())
                .addHeader("x-rapidapi-host", ojRapidApiConfig.getHost())
                .build();


        Response response = client.newCall(request).execute();
//        ResponseBody responseBody = response.body();

        log.info("status: {}", response);
        return response;
    }


    /**
     * 获取支持的语言种类
     */
    public Response getLanguages() throws IOException {
        OkHttpClient client = new OkHttpClient();

        Request request = new Request.Builder()
                .url("https://" + ojRapidApiConfig.getHost() + "/languages")
                .get()
                .addHeader("x-rapidapi-key", ojRapidApiConfig.getKey())
                .addHeader("x-rapidapi-host", ojRapidApiConfig.getHost())
                .build();

        Response response = client.newCall(request).execute();
        return response;
    }


    /**
     * 提交代码，返回提交凭证 submissionToken
     */
    public String submitCode(Integer languageId, String codeBase64, String stdinBase64, String stdoutExpected) throws IOException {
        OkHttpClient client = new OkHttpClient();
        MediaType mediaType = MediaType.parse("application/json");

        if (languageId == null || !OjConstant.languages.containsKey(languageId))
            languageId = OjConstant.LANGUAGE_PYTHON3;

        String requestBodyDataJson;
        if (stdoutExpected != null)
            requestBodyDataJson = String.format("{\"language_id\":%d,\"source_code\":\"%s\",\"stdin\":\"%s\",\"expected_output\":\"%s\"}",
                languageId, codeBase64, stdinBase64, stdoutExpected);
        else
            requestBodyDataJson = String.format("{\"language_id\":%d,\"source_code\":\"%s\",\"stdin\":\"%s\"}",
                    languageId, codeBase64, stdinBase64);

        RequestBody body = RequestBody.create(mediaType, requestBodyDataJson);
        Request request = new Request.Builder()
                .url("https://" + ojRapidApiConfig.getHost() + "/submissions?base64_encoded=true&wait=false&fields=*")
                .post(body)
                .addHeader("x-rapidapi-key", ojRapidApiConfig.getKey())
                .addHeader("x-rapidapi-host", ojRapidApiConfig.getHost())
                .build();

        Response response = client.newCall(request).execute();
        if (!response.isSuccessful())
            throw new IOException("Failed to submit code type " + OjConstant.languages.get(languageId));

        // JSON-ify submission ticket
        String responseBody = response.body().string();
        JSONObject jsonObject = new JSONObject(responseBody);
        String submissionToken = jsonObject.getString("token");
        log.info("提交代码成功，返回提交凭证： token = [{}]", submissionToken);
        return submissionToken;
    }

    /**
     * 根据提交凭证 submissionToken 代码提交状态
     */
    public Response getSubmission(String submissionToken) throws IOException {
        OkHttpClient client = new OkHttpClient();

        String requestUrl = String.format("https://%s/submissions/%s?base64_encoded=true&fields=*", ojRapidApiConfig.getHost(), submissionToken);

        Request request = new Request.Builder()
                .url(requestUrl)
                .get()
                .addHeader("x-rapidapi-key", ojRapidApiConfig.getKey())
                .addHeader("x-rapidapi-host", ojRapidApiConfig.getHost())
                .build();

        Response response = client.newCall(request).execute();
        return response;
    }
}
